package study.web.social;

import javax.annotation.Resource;
import javax.validation.Valid;

import lombok.extern.slf4j.Slf4j;

import org.springframework.social.connect.Connection;
import org.springframework.social.connect.UserProfile;
import org.springframework.social.connect.web.ProviderSignInUtils;
import org.springframework.stereotype.Controller;
import org.springframework.validation.BindingResult;
import org.springframework.validation.ObjectError;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.context.request.WebRequest;

import study.domain.user.User;
import study.service.user.UserService;
import study.web.security.SecuritySupport;
import study.web.user.SignupForm;

@Slf4j
@Controller
@RequestMapping(value = "/sns")
public class SignController {

	@Resource(name = "userService")
	private UserService userService;

	@Resource(name = "securitySupport")
	private SecuritySupport securitySupport;

	/**
	 * 계정 가입 신청
	 */
	@RequestMapping(value = "/signup", method = RequestMethod.GET)
	public SignupForm signupForm(WebRequest request) {
		Connection<?> connection = ProviderSignInUtils.getConnection(request);
		if (connection != null) {
			return fromProviderUser(connection.fetchUserProfile());
		} else {
			return new SignupForm();
		}
	}

	private SignupForm fromProviderUser(UserProfile providerUser) {
		log.debug("providerUser={}", providerUser);
		SignupForm form = new SignupForm();
		form.setUsername(providerUser.getUsername());
		form.setName(providerUser.getLastName() + " "
				+ providerUser.getFirstName());
		return form;
	}

	@RequestMapping(value = "/signup", method = RequestMethod.POST)
	public String signup(@Valid SignupForm form, BindingResult formBinding,
			WebRequest request) {
		if (formBinding.hasErrors()) {
			log.debug("error={}", formBinding.getAllErrors());
			return null;
		}
		User user = createUser(form, formBinding);
		if (user != null) {
			if (userService.hasUserByUsername(user.getUsername())) {
				formBinding.addError(new ObjectError("username",
						new String[] { "signup.username.already_use" }, null,
						"username has already registered"));
				return null;
			}
			if (userService.addNormalUser(user).getUserId() != null) {
				securitySupport.setAuthentication(user.getUsername());
				securitySupport.setSessionUser(request, user.getUsername());
				ProviderSignInUtils.handlePostSignUp(user.getUsername(),
						request);
				return "redirect:/";
			}
		}
		return null;
	}

	private User createUser(SignupForm form, BindingResult formBinding) {
		User user = new User();
		user.setUsername(form.getUsername());
		user.setPassword(form.getPassword());
		user.setName(form.getName());
		user.setEnabled(true);
		return user;
	}
}
